#include <iostream>
#include <tuple>

using namespace std;

namespace FactoryTDetail
{
	template<typename T>
	struct _Construct
	{
		template<typename... Args>
		T* create(const Args&... args)
		{
			return new T(args...);
		}
	};

	template<>
	struct _Construct<void>
	{
		template<typename... Args>
		void* create(const Args&...) { return NULL; }
	};
}

template<typename T = void>
struct FactoryT
{
	virtual T* create() = 0;
};

template<typename T, typename... Args>
struct FactoryTArgs : public FactoryT<T>
{
	std::tuple<Args...> _tuple;

	FactoryTArgs(const Args&... args) : _tuple(std::make_tuple(args...)) {}
	T* create() override
	{
		return create(_tuple, std::index_sequence_for<Args...>());
	}

private:
	template <typename _Tuple, size_t... _Indexes>
	T* create(const _Tuple& _tp, std::index_sequence<_Indexes...>)
	{
		return FactoryTDetail::_Construct<T>{}.create(get<_Indexes>(move(_tp))...);
	}
};

template<typename T = void, typename... Args>
FactoryT<T>* createFactoryT(const Args&... args)
{
	return new FactoryTArgs<T, Args...>(args...);
}

struct A
{
	int _i1 = 0;
	int _i2 = 0;
	int _i3 = 0;

	A(int i1, int i2, int i3) : _i1(i1), _i2(i2), _i3(i3) {}
};

int main()
{

	FactoryT<A>* pFactoryA = createFactoryT<A>(1, 2, 3);
	A* pA = pFactoryA->create();
	cout << "i1=" << pA->_i1 << endl;
	cout << "i2=" << pA->_i2 << endl;
	cout << "i3=" << pA->_i3 << endl;

	auto pFactory = createFactoryT(1, 2, 3);
	auto pT = pFactory->create();
	cout << pT << endl;

	return 0;
}